package regexEnrichment;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.*;
import java.io.*;

import com.google.common.collect.*;
import markovChain.*; 

public class Tester {
	
	public static void testGenerateMarkovModel(){
		String sequence= "GATCACAGGTCTATCACCCTATTAACCACTCACGGGAGCTCTCCATGCATTTGGTATTTTCGTCTGGGGGGTGTGCACGCGATAGCATTGCGAGACGCTGGAGCCGGAGCACCCTATGTCGCAGTATCTGTCTTTGATTCCTGCCTCATTCTATTATTTATCGCACCTACGTTCAATATTACAGGCGAACATACCTACTAAAGTGTGTTAATTAATTAATGCTTGTAGGACATAATAATAACAATTGAATGTCTGCACAGCCGCTTTCCACACAGACATCATAACAAAAAATTTCCACCAAACCCCCCCCTCCCCCCGCTTCTGGCCACAGCACTTAAACACATCTCTGCCAAACCCCAAAAACAAAGAACCCTAACACCAGCCTAACCAGATTTCAAATTTTATCTTTAGGCGGTATGCACTTTTAACAGTCACCCCCCAACTAACACATTATTTTCCCCTCCCACTCCCATACTACTAATCTCATCAATACAACCCCCGCCCATCCTACCCAGCACACACACACCGCTGCTAACCCCATACCCCGAACCAACCAAACCCCAAAGACACCCCCCACAGTTTATGTAGCTTACCTCCTCAAAGCAATACACTGAAAATGTTTAGACGGGCTCACATCACCCCATAAACAAATAGGTTTGGTCCTAGCCTTTCTATTAGCTCTTAGTAAGATTACACATGCAAGCATCCCCGTTCCAGTGAGTTCACCCTCTAAATCACCACGATCAAAAGGGACAAGCATCAAGCACGCAGCAATGCAGCTCAAAACGCTTAGCCTAGCCACACCCCCACGGGAAACAGCAGTGATTAACCTTTAGCAATAAACGAAAGTTTAACTAAGCTATACTAACCCCAGGGTTGGTCAATTTCGTGCCAGCCACCGCGGTCACACGATTAACCCAAGTCAATAGAAGCCGGCGTAAAGAGTGTTTTAGATCACCCCCTCCCCAATAAAGCTAAAACTCACCTGAGTTGTAAAAAACTCCAGTTGACACAAAATAGACTACGAAAGTGGCTTTAACATATCTGAACACACAATAGCTAAGACCCAAACTGGGATTAGATACCCCACTATGCTTAGCCCTAAACCTCAACAGTTAAATCAACAAAACTGCTCGCCAGAACACTACGAGCCACAGCTTAAAACTCAAAGGACCTGGCGGTGCTTCATATCCCTCTAGA";
		int order= 2;
		double pctUnobserved= 0.01;
		markovChain.Model model= Tools.generateMarkovModel(order, sequence, pctUnobserved);
		System.out.println(model);
	}
	
	public static void testGenerateRandomSequenceMarkov(){
		String sequence= "GATCACAGGTCTATCACCCTATTAACCACTCACGGGAGCTCTCCATGCATTTGGTATTTTCGTCTGGGGGGTGTGCACGCGATAGCATTGCGAGACGCTGGAGCCGGAGCACCCTATGTCGCAGTATCTGTCTTTGATTCCTGCCTCATTCTATTATTTATCGCACCTACGTTCAATATTACAGGCGAACATACCTACTAAAGTGTGTTAATTAATTAATGCTTGTAGGACATAATAATAACAATTGAATGTCTGCACAGCCGCTTTCCACACAGACATCATAACAAAAAATTTCCACCAAACCCCCCCCTCCCCCCGCTTCTGGCCACAGCACTTAAACACATCTCTGCCAAACCCCAAAAACAAAGAACCCTAACACCAGCCTAACCAGATTTCAAATTTTATCTTTAGGCGGTATGCACTTTTAACAGTCACCCCCCAACTAACACATTATTTTCCCCTCCCACTCCCATACTACTAATCTCATCAATACAACCCCCGCCCATCCTACCCAGCACACACACACCGCTGCTAACCCCATACCCCGAACCAACCAAACCCCAAAGACACCCCCCACAGTTTATGTAGCTTACCTCCTCAAAGCAATACACTGAAAATGTTTAGACGGGCTCACATCACCCCATAAACAAATAGGTTTGGTCCTAGCCTTTCTATTAGCTCTTAGTAAGATTACACATGCAAGCATCCCCGTTCCAGTGAGTTCACCCTCTAAATCACCACGATCAAAAGGGACAAGCATCAAGCACGCAGCAATGCAGCTCAAAACGCTTAGCCTAGCCACACCCCCACGGGAAACAGCAGTGATTAACCTTTAGCAATAAACGAAAGTTTAACTAAGCTATACTAACCCCAGGGTTGGTCAATTTCGTGCCAGCCACCGCGGTCACACGATTAACCCAAGTCAATAGAAGCCGGCGTAAAGAGTGTTTTAGATCACCCCCTCCCCAATAAAGCTAAAACTCACCTGAGTTGTAAAAAACTCCAGTTGACACAAAATAGACTACGAAAGTGGCTTTAACATATCTGAACACACAATAGCTAAGACCCAAACTGGGATTAGATACCCCACTATGCTTAGCCCTAAACCTCAACAGTTAAATCAACAAAACTGCTCGCCAGAACACTACGAGCCACAGCTTAAAACTCAAAGGACCTGGCGGTGCTTCATATCCCTCTAGA";
		int order= 2;
		double pctUnobserved= 0.01;
		markovChain.Model model= Tools.generateMarkovModel(order, sequence, pctUnobserved);
		int i= 0;
		long t0= System.currentTimeMillis();
		while (i < 10000){
			String rndsequence= Tools.generateRandomSequence(model, sequence.length());		
			i++;
		}
		long t1= System.currentTimeMillis();
		System.out.println("testGenerateMarkovModel: " + (t1-t0) + " ms");	
//		System.out.println(rndsequence);
	}
	
	public static void testNucleotideFrequencies(){
		String x= "GATCACAGGTCTATCACCCTATTAACCACTCACGGGAGCTCTCCATGCATTTGGTATTTTCGTCTGGGGGGTGTGCACGCGATAGCATTGCGAGACGCTGGAGCCGGAGCACCCTATGTCGCAGTATCTGTCTTTGATTCCTGCCTCATTCTATTATTTATCGCACCTACGTTCAATATTACAGGCGAACATACCTACTAAAGTGTGTTAATTAATTAATGCTTGTAGGACATAATAATAACAATTGAATGTCTGCACAGCCGCTTTCCACACAGACATCATAACAAAAAATTTCCACCAAACCCCCCCCTCCCCCCGCTTCTGGCCACAGCACTTAAACACATCTCTGCCAAACCCCAAAAACAAAGAACCCTAACACCAGCCTAACCAGATTTCAAATTTTATCTTTAGGCGGTATGCACTTTTAACAGTCACCCCCCAACTAACACATTATTTTCCCCTCCCACTCCCATACTACTAATCTCATCAATACAACCCCCGCCCATCCTACCCAGCACACACACACCGCTGCTAACCCCATACCCCGAACCAACCAAACCCCAAAGACACCCCCCACAGTTTATGTAGCTTACCTCCTCAAAGCAATACACTGAAAATGTTTAGACGGGCTCACATCACCCCATAAACAAATAGGTTTGGTCCTAGCCTTTCTATTAGCTCTTAGTAAGATTACACATGCAAGCATCCCCGTTCCAGTGAGTTCACCCTCTAAATCACCACGATCAAAAGGGACAAGCATCAAGCACGCAGCAATGCAGCTCAAAACGCTTAGCCTAGCCACACCCCCACGGGAAACAGCAGTGATTAACCTTTAGCAATAAACGAAAGTTTAACTAAGCTATACTAACCCCAGGGTTGGTCAATTTCGTGCCAGCCACCGCGGTCACACGATTAACCCAAGTCAATAGAAGCCGGCGTAAAGAGTGTTTTAGATCACCCCCTCCCCAATAAAGCTAAAACTCACCTGAGTTGTAAAAAACTCCAGTTGACACAAAATAGACTACGAAAGTGGCTTTAACATATCTGAACACACAATAGCTAAGACCCAAACTGGGATTAGATACCCCACTATGCTTAGCCCTAAACCTCAACAGTTAAATCAACAAAACTGCTCGCCAGAACACTACGAGCCACAGCTTAAAACTCAAAGGACCTGGCGGTGCTTCATATCCCTCTAGA";
		System.out.println(Tools.nucleotideComposition(x));
		System.out.println(Tools.nucleotideFrequencies(x, 100));
		System.out.println(Tools.nucleotideFrequencies(x, 10));
	}
	public static void timeitRandom(){
		int i= 0;
		long t0= System.currentTimeMillis();
		Random rnd= new Random();
		while (i < (10000 * 1000) ){
			rnd.nextFloat();
			i++;
		}
		long t1= System.currentTimeMillis();
		System.out.println("random: " + (t1-t0));
	}
	
	public static void timeitGenerateRandomSequence(){
		HashMap<String, Float> map= new HashMap<String, Float>();
		map.put("A", (float)0.25);
		map.put("C", (float)0.25);
		map.put("G", (float)0.25);
		map.put("T", (float)0.25);
		map.put("N", (float)0.25);

		// Timeit:
		int i= 0;
		long t0= System.currentTimeMillis();
		while(i < 10000){
			String xx= Tools.generateRandomSequence(map, 1000); // 10000000
			i++;
		}
		long t1= System.currentTimeMillis();
		System.out.println("generateRandomSequence: " + (t1-t0) + "ms");
	}
	
	public static void timeitGenerateRandomSequence2(){
		HashMap<String, Float> map= new HashMap<String, Float>();
		map.put("A", (float)0.25);
		map.put("C", (float)0.25);
		map.put("G", (float)0.25);
		map.put("T", (float)0.25);
		map.put("N", (float)0.25);

		String[] nucleotides= new String[map.size()];
		float[] nucleotProb= new float[map.size()];
		int x= 0;
		for (String k : map.keySet()){
			nucleotides[x]= k;
			nucleotProb[x]= map.get(k);
			x++;
		}
		
		// Timeit:
		int i= 0;
		long t0= System.currentTimeMillis();
		while(i < 10000){
			String xx= Tools.generateRandomSequence(nucleotides, nucleotProb, 1000); // 10000000
			i++;
		}
		long t1= System.currentTimeMillis();
		System.out.println("generateRandomSequence2: " + (t1-t0) + "ms");
	}
	
	public static void timeitRegexCounter(){
		String xsequence= "AAGCCTACGGGCGGGGGTTGGGGGGGCGTGTGTTGCAGGAGCAAAGTCGCACGGCGCCGGGCTGGGGCGGGGGGAGGGTGGCGCCGTGCACGCGCAGAAACTCACGTCACGGTGGCGCGGCGCAGAGACGGGTAGAACCTCAGTAATCCGAAAAGCCGGGATCGACCGCCCCTTGCTTGCAGCCGGGCACTACAGGACCCGCTTGCTCACGGTGCTGTGCCAGGGCGCCCCCTGCTGGCGACTAGGGCAACTGCAGGGCTCTCTTGCTTAGAGTGGTGGCCAGCGCCCCCTGCTGGCGCCGGGGCACTGCAGGGCCCTCTTGCTTACTGTATAGTGGTGGCACGCCGCCTGCTGGCAGCTAGGGACATTGCAGGGTCCTCTTGCTCAAGGTGTAGTGGCAGCACGCCCACCTGCTGGCAGCTGGGGACACTGCCGGGCCCTCTTGCTCCAACAGTACTGGCGGATTATAGGGAAACACCCGGAGCATATGCTGTTTGGTCTCAGTAGACTCCTAAATATGGGATTCCTGGGTTTAAAAGTAAAAAATAAATATGTTTAATTTGTGAACTGATTACCATCAGAATTGTACTGTTCTGTATCCCACCAGCAATGTCTAGGAATGCCTGTTTCTCCACAAAGTGTTTACTTTTGGATTTTTGCCAGTCTAACAGGTGAAGCCCTGGAGATTCTTATTAGTGATTTGGGCTGGGGCCTGGCCATGTGTATTTTTTTAAATTTCCACTGATGATTTTGCTGCATGGCCGGTGTTGAGAATGACTGCGCAAATTTGCCGGATTTCCTTTGCTGTTCCTGCATGTAGTTTAAACGAGATTGCCAGCACCGGGTATCATTCACCATTTTTCTTTTCGTTAACTTGCCGTCAGCCTTTTCTTTGACCTCTTCTTTCTGTTCATGTGTATTTGCTGTCTCTTAGCCCAGACTTCCCGTGTCCTTTCCACCGGGCCTTTGAGAGGTCACAGGGTCTTGATGCTGTGGTCTT";
		String mpattern= "([gG]{3,}\\w{1,7}){3,}[gG]{3,}";
		Pattern xpattern= Pattern.compile("GGG");
		long t0= System.currentTimeMillis();
		int i= 0;
		while (i < 10000){
			Tools.regexCounter(xpattern, xsequence, true);
			i++;
		}
		long t1= System.currentTimeMillis();
		System.out.println("regexCounter: " + (t1-t0) + "ms");
	}
	
	// Timeit
	public static void timeitGenerateNullDistribution(){
		String sequence= "AAGCCTACGGGCGGGGGTTGGGGGGGCGTGTGTTGCAGGAGCAAAGTCGCACGGCGCCGGGCTGGGGCGGGGGGAGGGTGGCGCCGTGCACGCGCAGAAACTCACGTCACGGTGGCGCGGCGCAGAGACGGGTAGAACCTCAGTAATCCGAAAAGCCGGGATCGACCGCCCCTTGCTTGCAGCCGGGCACTACAGGACCCGCTTGCTCACGGTGCTGTGCCAGGGCGCCCCCTGCTGGCGACTAGGGCAACTGCAGGGCTCTCTTGCTTAGAGTGGTGGCCAGCGCCCCCTGCTGGCGCCGGGGCACTGCAGGGCCCTCTTGCTTACTGTATAGTGGTGGCACGCCGCCTGCTGGCAGCTAGGGACATTGCAGGGTCCTCTTGCTCAAGGTGTAGTGGCAGCACGCCCACCTGCTGGCAGCTGGGGACACTGCCGGGCCCTCTTGCTCCAACAGTACTGGCGGATTATAGGGAAACACCCGGAGCATATGCTGTTTGGTCTCAGTAGACTCCTAAATATGGGATTCCTGGGTTTAAAAGTAAAAAATAAATATGTTTAATTTGTGAACTGATTACCATCAGAATTGTACTGTTCTGTATCCCACCAGCAATGTCTAGGAATGCCTGTTTCTCCACAAAGTGTTTACTTTTGGATTTTTGCCAGTCTAACAGGTGAAGCCCTGGAGATTCTTATTAGTGATTTGGGCTGGGGCCTGGCCATGTGTATTTTTTTAAATTTCCACTGATGATTTTGCTGCATGGCCGGTGTTGAGAATGACTGCGCAAATTTGCCGGATTTCCTTTGCTGTTCCTGCATGTAGTTTAAACGAGATTGCCAGCACCGGGTATCATTCACCATTTTTCTTTTCGTTAACTTGCCGTCAGCCTTTTCTTTGACCTCTTCTTTCTGTTCATGTGTATTTGCTGTCTCTTAGCCCAGACTTCCCGTGTCCTTTCCACCGGGCCTTTGAGAGGTCACAGGGTCTTGATGCTGTGGTCTT";
		Pattern cpattern= Pattern.compile("GGG");
		int orderMarkovChain= 2;
		double pctPseudocounts= 0.01;
		int obsHits= 50; // Number of actual matches of "pattern" in "sequence"
		long t0= System.currentTimeMillis();
		TreeMultiset<Integer> hits= TreeMultiset.create();
		
		NullDistribution nd= new NullDistribution(sequence, orderMarkovChain, pctPseudocounts);
		System.out.println(nd.toString());
		nd.generateNullDistribution(sequence, cpattern, 50000, 20, obsHits, hits, true);
		
		long t1= System.currentTimeMillis();
		System.out.println("generateNullDistribution: " + (t1-t0) + " ms");
	}

	public static void timeitMapObservedHitsToNull(){
		TreeMultiset<Integer> mset= TreeMultiset.create(); 
		int i= 0;
		while (i < 10){ // Set of k ints each repeated i times. 
			int k= 0;
			while (k < 1000){ // Speed depends a lot on this. 
				mset.add(k);
				k++;
			}
			i++;
		}
		long t0= System.currentTimeMillis();
		i= 0;
		float p= -1;
		while (i < 1000000){
			p= Tools.mapObservedHitsToNull(mset, 9);
			i++;
		}
		long t1= System.currentTimeMillis();
		System.out.println("mapObservedHitsToNull: " + (t1-t0) + "ms; pval= " + p + "; Multiset: " + mset);
	}
	
	public static void testRegexCounter(){
		String xsequence= "AAGCCTACGGGCGGGGGTTGGGGGGGCGTGTGTTGCAGGAGCAAAGTCGCACGGCGCCGGGCTGGGGCGGGGGGAGGGTGGCGCCGTGCACGCGCAGAAACTCACGTCACGGTGGCGCGGCGCAGAGACGGGTAGAACCTCAGTAATCCGAAAAGCCGGGATCGACCGCCCCTTGCTTGCAGCCGGGCACTACAGGACCCGCTTGCTCACGGTGCTGTGCCAGGGCGCCCCCTGCTGGCGACTAGGGCAACTGCAGGGCTCTCTTGCTTAGAGTGGTGGCCAGCGCCCCCTGCTGGCGCCGGGGCACTGCAGGGCCCTCTTGCTTACTGTATAGTGGTGGCACGCCGCCTGCTGGCAGCTAGGGACATTGCAGGGTCCTCTTGCTCAAGGTGTAGTGGCAGCACGCCCACCTGCTGGCAGCTGGGGACACTGCCGGGCCCTCTTGCTCCAACAGTACTGGCGGATTATAGGGAAACACCCGGAGCATATGCTGTTTGGTCTCAGTAGACTCCTAAATATGGGATTCCTGGGTTTAAAAGTAAAAAATAAATATGTTTAATTTGTGAACTGATTACCATCAGAATTGTACTGTTCTGTATCCCACCAGCAATGTCTAGGAATGCCTGTTTCTCCACAAAGTGTTTACTTTTGGATTTTTGCCAGTCTAACAGGTGAAGCCCTGGAGATTCTTATTAGTGATTTGGGCTGGGGCCTGGCCATGTGTATTTTTTTAAATTTCCACTGATGATTTTGCTGCATGGCCGGTGTTGAGAATGACTGCGCAAATTTGCCGGATTTCCTTTGCTGTTCCTGCATGTAGTTTAAACGAGATTGCCAGCACCGGGTATCATTCACCATTTTTCTTTTCGTTAACTTGCCGTCAGCCTTTTCTTTGACCTCTTCTTTCTGTTCATGTGTATTTGCTGTCTCTTAGCCCAGACTTCCCGTGTCCTTTCCACCGGGCCTTTGAGAGGTCACAGGGTCTTGATGCTGTGGTCTT";
		Pattern xpattern= Pattern.compile("aaGCCTACGGGCGGGGGTTGG", 2);
		int c= Tools.regexCounter(xpattern, xsequence, true);
		System.out.println("regexCounter: " + c + " matches");
	}
	
	public static void main(String[] args){
		
		timeitGenerateNullDistribution();
		System.exit(0);
		
		testGenerateMarkovModel();
		
		testGenerateRandomSequenceMarkov();
		
		
		
		System.out.println(Tools.formatPvalue(1/(float)3, 90000));
		
		testRegexCounter();
		
		timeitRandom();
		timeitGenerateRandomSequence();
		timeitGenerateRandomSequence2();
		timeitRegexCounter();

		timeitMapObservedHitsToNull();
		System.exit(0);		
		
		testNucleotideFrequencies();
		
		System.out.println(1/(float)100 == (float)0.01);
		
		BufferedWriter log;

		log = new BufferedWriter(Tools.printer(null)); //stdout
		try {
			log.write("text");
			log.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.exit(0);
		
		ProbsLookUpTable p= new ProbsLookUpTable(100, "GGG", 1000, 20, 5);
		p.probsLookUpTable= new HashMap<Map<String, Float>, TreeMultiset<Integer>>();
		p.writeMap("test_data/mymap.ser");

		ProbsLookUpTable p2= new ProbsLookUpTable().readMap("test_data/mymap.ser"); 
		p2.setPattern("cccc");
		
		System.out.println(p.toString());
		System.out.println(p2.toString());

		System.exit(0);
		
		float pvalue= (float)0.333333333333;
		pvalue= Math.round(pvalue * 100) / (float) 100;
		System.out.println(pvalue);
		
		String x= "AAAAACCCCCGGGGGTTTTTACTGNACTGN";
		List<SeqMatcher> lst= Tools.regexMatcher(Pattern.compile("CCCCC"), x, true);

		for (SeqMatcher m : lst){
			System.out.println( m.toString() );
		}
		System.exit(0);
		
		Window w= new Window();
		List<Window> windowCoords= new ArrayList<Window>();

		w.setStart(0);
		w.setEnd(15);
		w.setSequence("AACCTTGGNNaaaaa");
		windowCoords.add(w);
	
		w= new Window();
		w.setStart(10);
		w.setEnd(25);
		w.setSequence("AACCTTGGNNaaaaa");
		windowCoords.add(w);

		ContigWindows cw= new ContigWindows();
		cw= new ContigWindows("seq1", "AAAAACCCCCGGGGGTTTTTACTGNACTGN");
		cw.setWindowCoords(5, 5);
		
		System.out.println(cw.toString());
	}
}
